import { Feature } from "ol";
import { Point } from "ol/geom";
import { Fill, Icon, Stroke, Style, Text } from "ol/style";
import { Vector as VectorSource } from "ol/source";
import { Vector as VectorLayer } from "ol/layer";
import { MapUtils } from "./MapUtils";
import LayerManager from "./LayerManager";
import { GeoJSONManager } from "./layerDataManager";
import mapStore from "@/stores/modules/map";


// export interface ModelConfig {
//     id: string,
//     name: string,
//     epoch: number,// 起始时间
//     model: {
//         img: string,  // 图片路径
//         scale: number,
//         type: string
//     },
//     position: {
//         heading: Array<any> // 水平角信息 [0.2,0.1.....],
//         coordinate: Array<any>, // 坐标信息  [[0,0],[1,1]]
//         information: Array<any>  // 其他信息 [[{id:123,name:456}]]
//     }
// }
export interface ModelConfig {
    id: string,
    name: string,
    epoch: number,// 起始时间
    model?: {
        img: string,  // 图片路径
        scale: number,
        type: string
    },
    position: {
        heading?: Array<any> // 水平角信息 [0.2,0.1.....],
        coordinate: Array<any>, // 坐标信息  [[0,0],[1,1]]
        time: Array<any>, // 时间信息 [0,1,2,3,4,5]
        information?: Array<any>  // 其他信息 [[{id:123,name:456}]]
    }
}


export interface olCzmlConfig {
    id: string,  // czml标识 / 数据标识
    clock: {
        interval: string,  // 时间区间 "开始时间戳/结束时间戳"
        currentTime: string, //  当前时间 时间戳
        multiplier: number, // 播放 速度  默认为1
        loopPlayback: number // 0循环 1 不循环
    },
    data: Array<ModelConfig>
}

export interface clockType {
    startTime: number;
    endTime: number;
    currentTime: number;
}

export interface ModelStyleOptions {
    id: string,
    iconSrc: string;
    modelName: string;
    heading: number; // 旋转角度
    scale: number;   // 缩放比例
    coordinates: [number, number]; // 模型坐标
}

export interface modelMove {

}

export class TimeLineManager {
    private correspondingStartTime: Array<any> = [];  // 每个起始时间对应的模型/模型id
    public clock: clockType | undefined;
    public czml: olCzmlConfig | undefined
    private layrMgr: LayerManager | undefined;
    private mapStore = mapStore();
    private prevBearing: number | null = null; // 上一个航向角


    init(czml: olCzmlConfig) {
        this.czml = czml
        // 组件时间轴系统
        let time = czml.clock.interval.split('/')
        this.clock = {} as clockType; // 或者确保 czml.clock 是必定存在的
        this.clock.currentTime = Number(czml.clock.currentTime);
        this.clock.startTime = Number(time[0])
        this.clock.endTime = Number(time[1])

        // 先添加模型 ， 但是不显示
        this.addModelMgr()
    }

    // 获取时间帧对应的数据
    dataCorrespondingToTheTimeFrame(currentTime: number) {
        this.correspondingStartTime.forEach(item => {
            let timeIndex = currentTime - item.timeReally;  // 计算相对时间

            const ss = this.czml?.data.find(m => m.id == item.id)
            if (timeIndex >= 0) {
                this.layrMgr?.setVisble(true, ss?.id)
                timeIndex = timeIndex * 0.001
                timeIndex = Math.floor(timeIndex)
                // this.addModel({ id: ss?.id, iconSrc: "../../public/image/FJ.png", heading: 90, scale: 2, coordinates: MapUtils.lonLatToMapCoord(ss?.position.coordinate[timeIndex][0], ss?.position.coordinate[timeIndex][1]) })
            } else if (timeIndex < 0) {
                this.layrMgr?.setVisble(false, ss?.id)
            }

            if (timeIndex >= 0 && timeIndex < ss?.position.coordinate.length) {
                const currentData = ss?.position.coordinate[timeIndex]
                const nextData = ss?.position.coordinate[timeIndex + 1]
                let current = { time: ss?.position.time[timeIndex], coordinates: MapUtils.lonLatToMapCoord(ss?.position.coordinate[timeIndex][0], ss?.position.coordinate[timeIndex][1]) }
                let next = { time: ss?.position.time[timeIndex + 1], coordinates: MapUtils.lonLatToMapCoord(ss?.position.coordinate[timeIndex + 1][0], ss?.position.coordinate[timeIndex + 1][1]) }
                const heading = this.calculateHeading(currentData[1], currentData[0], nextData[1], nextData[0])


                const deltaTime = (currentTime - ss?.position.time[timeIndex - 1]) / 1000 * this.mapStore.timeIntervalValue; // 计算经过的时间
                this.interpolate(current, next, deltaTime)
                this.udpdateFeature({ id: ss?.id, iconSrc: ss?.model?.img, modelName: ss?.name, heading: heading, scale: ss?.model?.scale, coordinates: MapUtils.lonLatToMapCoord(ss?.position.coordinate[timeIndex][0], ss?.position.coordinate[timeIndex][1]) })
                // 航迹管理
                this.updateTrajectory(ss?.id + "_line", ss?.position.coordinate.slice(0, timeIndex))
            }
        })


    }


    //                                          回放模型处理                                                  //

    // 设置模型样式
    setModelStyle({ iconSrc, modelName, heading, scale, coordinates }: ModelStyleOptions) {
        const textStyle = this.createTextStyle(modelName);
        const iconStyle = this.createIconStyle(iconSrc, heading, scale);

        // 创建 Feature
        const feature = this.createFeature(coordinates);

        // 设置 Feature 样式
        feature.setStyle(new Style({
            image: iconStyle,
            text: textStyle
        }));

        return feature;
    }

    // 创建文本样式
    createTextStyle(modelName: string) {
        return new Text({
            text: modelName,
            scale: 1.5,
            offsetY: -35, // 文本偏移
            fill: new Fill({ color: '#FFF' }),
            stroke: new Stroke({
                color: '#000000',
                width: 2,
            }),
            backgroundFill: new Fill({ // 背景颜色  
                color: 'rgba(0, 0, 0, 0.5)',
            }),
            padding: [5, 5, 5, 5], // 背景填充边距  
        });
    }

    // 创建图标样式
    createIconStyle(src: string, heading: number, scale: number) {
        return new Icon({
            src: src,
            scale: scale,
            rotation: this.degreesToRadians(heading),
            anchor: [0.5, 0.5], // 图标中心对齐
        });
    }

    // 创建一个 Feature
    createFeature(coordinates: [number, number]) {
        return new Feature({
            geometry: new Point(coordinates)
        });
    }

    //  将模型 Feature 添加到图层
    addFeatureToLayer(feature: Feature, vectorLayer: VectorLayer) {
        const source = vectorLayer.getSource();
        source?.addFeature(feature);
    }

    // 修改 Feature 
    udpdateFeature(modelStyle: ModelStyleOptions) {
        //  设置模型样式
        const modelFeature = this.setModelStyle(modelStyle);
        this.layrMgr?.updateLayer(modelStyle.id, modelFeature)
    }

    //将角度转换为弧度
    degreesToRadians(degrees: number): number {
        return (degrees * Math.PI) / 180;
    }

    // 添加模型管理
    addModelMgr() {
        this.czml?.data.forEach((item, index) => {
            this.correspondingStartTime?.push({ timeReally: item.epoch, id: item.id })  // 存储对应模型起始时间和id
            // 添加模型操作
            this.addModel({ id: item.id, modelName: item.name, iconSrc: item.model?.img, heading: 90, scale: item.model?.scale, coordinates: MapUtils.lonLatToMapCoord(item.position.coordinate[0][0], item.position.coordinate[0][1]) })
            // 添加航迹
            this.createTrajectory(item.id + "_line", [])
            // 默认先隐藏 
            // 获取全局图层管理器
            this.layrMgr?.setVisble(false, item.id)
        })
    }
    // 添加回放模型到图层中
    addModel(modelStyle: ModelStyleOptions) {
        //  创建一个 VectorSource 和 VectorLayer
        let vectorSource = new VectorSource();
        const vectorLayer = new VectorLayer({
            source: vectorSource
        }); 
        vectorLayer.setZIndex(1)
        //  设置模型样式
        const modelFeature = this.setModelStyle(modelStyle);
        //  将 Feature 添加到图层
        this.addFeatureToLayer(modelFeature, vectorLayer);

        // 获取全局图层管理器
        this.layrMgr = (window as any).olMap.layerManager
        // 添加到图层
        this.layrMgr?.addLayer(vectorLayer, modelStyle.id, true)

    }

    // 移除图层上的模型
    clearModelById(modelId: string) {
        this.layrMgr?.removeLayer(modelId)
        this.layrMgr?.removeLayer(modelId+"_line")
    }

    // 假设飞机当前位置经纬度为 lat1, lon1，目标位置经纬度为 lat2, lon2
    calculateHeading(lat1: number, lon1: number, lat2: number, lon2: number) {
        // 原有计算代码
        lat1 = lat1 * Math.PI / 180;
        lon1 = lon1 * Math.PI / 180;
        lat2 = lat2 * Math.PI / 180;
        lon2 = lon2 * Math.PI / 180;

        const deltaLon = lon2 - lon1;
        const X = Math.cos(lat2) * Math.sin(deltaLon);
        const Y = Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(deltaLon);
        const bearing = Math.atan2(X, Y);

        let bearingDegrees = (bearing * 180 / Math.PI + 360) % 360;
        return Number(bearingDegrees.toFixed(4));
    }

    // 插值处理
    private interpolate(current: any, next: any, deltaTime: number): [number, number] {
        const totalDuration = (next.time - current.time); // 转换为毫秒
        const progress = Math.min(deltaTime / totalDuration, 1); // 计算当前进度

        const lat = current.coordinates[1] + (next.coordinates[1] - current.coordinates[1]) * progress;
        const lon = current.coordinates[0] + (next.coordinates[0] - current.coordinates[0]) * progress;
        return [lon, lat];
    }

    // 生成航迹
    createTrajectory(id: string, dataPath: Array<any>) {
        const geojson = GeoJSONManager.convertToLine(dataPath);
        const geoLayer = GeoJSONManager.loadMoreGeoJSON([geojson]);
        geoLayer.setZIndex(1)
        this.layrMgr?.addLayer(geoLayer, id, true)
    }

    // 修改航迹
    updateTrajectory(id: string, dataPath: Array<any>) {
        const geoLayer = this.layrMgr?.getLayerById(id);
        let source = geoLayer?.getSource()
        source?.clear()
        const geojson = GeoJSONManager.convertToLine(dataPath);
        const newSource = GeoJSONManager.getGeoSource([geojson],"EPSG:3857")
        const features = newSource.getFeatures()
        source?.addFeatures(features)
    }


    //                                         回放模型处理end                                                         //


    getTime() {
        return { startTime: this.clock?.startTime, endTime: this.clock?.endTime }
    }
}


